package fnic.prehand.esagent.activity_measure;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.common.xcontent.json.JsonXContentParser;

import fnic.jsontrans.DeviceId;
import fnic.jsontrans.ErrorCode;
import fnic.jsontrans.JHCdmaResult;
import fnic.jsontrans.JHCellIdResult;
import fnic.jsontrans.ObjectTestResult;
import fnic.jsontrans.PhoneJsonToCtrl;
import fnic.jsontrans.SubjectDescript;
import fnic.prehand.esagent.IndexAgent;

public class PhoneAgent extends CommonAgent{
	private static final Logger logger = Logger.getLogger(PhoneAgent.class);
	private PhoneJsonToCtrl phoneCtrl;
	private ArrayList<PhoneJsonToCtrl> phoneCtrlList;
	
	public PhoneAgent(String idx, String type, String ctrlUrl,  String skUrl) {
		super(idx, type, ctrlUrl, skUrl);
		phoneCtrlList = new ArrayList<PhoneJsonToCtrl>();
	}

	@Override
	boolean parseHead(String head, Jsonmaps maps) {
		JsonXContentParser headparser=null;
		Map<String, Object> headmap=null;
		boolean parseflg = true;
		int execnum = 1;
		
		try {
			headparser = (JsonXContentParser) jsoncontent.createParser(head);
			headmap = headparser.map();
		} catch (IOException e) {
			logger.error("parse head fail, reason:"+e.getMessage());
			parseflg = false;
		}finally{
			if(headparser!=null){
				headparser.close();
			}
			if(!parseflg || headmap==null){
				return false;
			}
		}
		
		if(headmap.containsKey(DeviceId.COND_PROBE_TYPE)){
			probeType = (Integer)headmap.get(DeviceId.COND_PROBE_TYPE);
		}else{
			probeType = 1;
		}
		probeId = (Integer)headmap.get(DeviceId.COND_PROBE_ID);
		if(headmap.containsKey(DeviceId.COND_EXEC_NUM)){
			execnum = (Integer)headmap.get(DeviceId.COND_EXEC_NUM);
		}
		
		long time = System.currentTimeMillis();
		Date date = new Date(time);
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String probeTime = dateFormat.format(date);
		
		phoneCtrl = new PhoneJsonToCtrl(new ObjectTestResult(probeId, execnum, probeTime));
		headmap.remove(DeviceId.COND_PROBE_ID);  //body里边有probeId这里删之
		if(headmap.containsKey(DeviceId.COND_PROBE_SESSION)){
			String sessionKey = (String)headmap.get(DeviceId.COND_PROBE_SESSION);
			if(!validSK(sessionKey)){
				phoneCtrl.getindexinfo().setindexid("-2"); // sessionKey校验失败
				phoneCtrl.getindexinfo().setStatus(ErrorCode.index_failed);
				phoneCtrl.getindexinfo().setErrorno(ErrorCode.sessionKeyErrCode);
				setFailmsg(jsonInstance.Obj2String(phoneCtrl));
				return false;
			}
		}
		headmap.remove(DeviceId.COND_PROBE_SESSION);
		
		//probetype,probetype冗余，兼容之前的手机发布版本
		headmap.put("probeType", probeType);
		headmap.put("probetype", probeType);
		headmap.put("probeId", probeId);
		headmap.put("probeid", probeId);
		headmap.put("probetime", probeTime);
		maps.setHeadmap(headmap);
		return true;
	}

	@Override
	boolean parseBody(String body, Jsonmaps maps) {
		JsonXContentParser bodyparser=null;
		Map<String, Object> bodymap=null;
		boolean parseflg = true;
		
		try {
			bodyparser = (JsonXContentParser) jsoncontent.createParser(body);
			bodymap = bodyparser.map();
		} catch (IOException e) {
			logger.error("parse body fail, reason:"+e.getMessage());
			parseflg = false;
		}finally{
			if(bodyparser!=null){
				bodyparser.close();
			}
			if(!parseflg){
				phoneCtrl.getindexinfo().setindexid("-1");
				phoneCtrl.getindexinfo().setStatus(ErrorCode.index_failed);
				phoneCtrl.getindexinfo().setErrorno(ErrorCode.jsonErrCode);
				setFailmsg(jsonInstance.Obj2String(phoneCtrl));
				return false;
			}
		}
		
		if(bodymap == null){
			return false;
		}
		else if(probeType == 2 ){
			dealPhoneReq(bodymap);
			phoneCtrlList.add(phoneCtrl);

		}

		maps.setBodymap(bodymap);
		return true;
	}

	@Override
	protected void dealBulkIndexRsp(BulkResponse response) {
		if(response == null){
			return;
		}
		if(response.hasFailures()){
			logger.error("failed to execute" + response.buildFailureMessage());
		}
		
		Iterator<BulkItemResponse> rspitor = response.iterator();
		int pos = 0;
		while (rspitor.hasNext()) {
				if(phoneCtrlList.get(pos).getindexinfo().getStatus() == ErrorCode.index_failed){
					pos++;
					continue;
				}
				BulkItemResponse rsp = rspitor.next();
				if (!rsp.isFailed()) {
					phoneCtrlList.get(pos).getindexinfo().setindexid(rsp.getId());
					phoneCtrlList.get(pos).getindexinfo().setStatus(ErrorCode.index_success);
					phoneCtrlList.get(pos).getindexinfo().setErrorno(0);
				} else {
					logger.error("bulk error details: position:" +pos+ ", failmsg:" + rsp.getFailureMessage());
					phoneCtrlList.get(pos).getindexinfo().setindexid("-2"); //批量索引失败
					phoneCtrlList.get(pos).getindexinfo().setStatus(ErrorCode.index_failed);
					phoneCtrlList.get(pos).getindexinfo().setErrorno(ErrorCode.indexErrCode);
				}
			pos++;
		}
		sendIdxResult(jsonInstance.Obj2String(phoneCtrlList), true);
		phoneCtrlList = new ArrayList<PhoneJsonToCtrl>();
	}

	
	/*
	 * 手机请求扩维
	 */
	private void dealPhoneReq(Map<String, Object> maps) {
		RadioCGI cgi = new RadioCGI();
		SubjectDescript subDescript = new SubjectDescript();
		//这里是个坑，从body里获取probeId，先不管了
//		if (maps.containsKey(DeviceId.COND_PROBE_ID)) {
//			subDescript.setprobeid((Integer) maps.get(DeviceId.COND_PROBE_ID));
//		}
		subDescript.setprobeid(probeId);
		if (maps.containsKey("netquality")) {
			subDescript.setnetquality((Integer) maps.get("netquality"));
		}
		if (maps.containsKey("callquality")) {
			subDescript.setcallquality((Integer) maps.get("callquality"));
		}			
		if (maps.containsKey("feedback")) {
			subDescript.setfeedback((String) maps.get("feedback"));
		}

		if(maps.containsKey("pos")){
			if(maps.get("pos") instanceof Map){
				Map<String, Double> posMap = (Map<String, Double>)maps.get("pos");
				double dblat = posMap.get("lat");
				double dblon = posMap.get("lon");
				subDescript.setlatitude(dblat);
				subDescript.setlongitude(dblon);
				maps.put("latitude", dblat);
				maps.put("longitude", dblon);
			}
		}
		
		
//		if (maps.containsKey("radius")) {
//			if (maps.get("radius") instanceof Integer) {
//				subDescript
//						.setRadius((double) (Integer) maps.get("radius"));
//			} else if (maps.get("radius") instanceof Float) {
//				subDescript.setRadius((double) (Float) maps.get("radius"));
//			} else {
//				subDescript.setRadius((Double) maps.get("radius"));
//			}
//		}
		
		if(maps.containsKey("position")){
			if(maps.get("position") instanceof Map){
				Map<String, String> positionMap = (Map<String, String>)maps.get("position");
				subDescript.setAddress(positionMap.get("address"));
			}
		}
		
		if(maps.containsKey("bs")){
			if(maps.get("bs") instanceof Map){
				Map<String, Integer> bsMap = (Map<String, Integer>)maps.get("bs");
				cgi.setA(bsMap.get("a"));
				cgi.setB(bsMap.get("b"));
				cgi.setC(bsMap.get("c"));
				cgi.setT(bsMap.get("t"));
				
				// 获取手机基站的经纬度位置信息
//				boolean posfg = getCGIPosbyGpsspg();
//				boolean posfg = getCGIPosbyCellid();
				boolean posfg = getCGIPosbyJuHe(cgi);
				if (posfg) {
					Map<String, Object> baseposMap = new HashMap<String, Object>();
					baseposMap.put("lat", cgi.getLatitude());
					baseposMap.put("lon", cgi.getLongitude());
					maps.put("baseposition", baseposMap);
				}
			}
		}
		
		//融合100环境，冗余下列字段
		if(maps.containsKey("ping")){
			if(maps.get("ping") instanceof Map){
				Map<String, Object> pingMap = (Map<String, Object>)maps.get("ping");
				maps.put("pingdelayavg", pingMap.get("mean_rtt_ms"));
				maps.put("packetloss", pingMap.get("packet_loss"));
			}
		}
		
		
		if(maps.containsKey("downlink")){
			if(maps.get("downlink") instanceof Map){
				Map<String, Object> downMap = (Map<String, Object>)maps.get("downlink");
				maps.put("downbandwith", downMap.get("avg_speed"));
			}
		}
		
		if(maps.containsKey("uplink")){
			if(maps.get("uplink") instanceof Map){
				Map<String, Object> upMap = (Map<String, Object>)maps.get("uplink");
				maps.put("upbandwith", upMap.get("avg_speed"));
			}
		}
		
		if(maps.containsKey(DeviceId.COND_TASK_ID)){
			int taskid = (Integer)maps.get(DeviceId.COND_TASK_ID);
			phoneCtrl.getindexinfo().setTaskid(String.valueOf(taskid));
			maps.put("taskid", taskid);
		}

		phoneCtrl.setdescription(subDescript);
	}
	
	private boolean getCGIPosbyJuHe(RadioCGI cgi){
		String urlPath = "http://58.215.185.154:8080/DemoServer/";
		int a = cgi.getA();
		int b = cgi.getB();
		int c = cgi.getC();
		int t = cgi.getT();
		
		//移动 联通
		if(t==0 || t==1){
			urlPath += "cellid_search?"+"mnc="+a+"&lac="+b+"&cell="+c+"&hex=0"; 
		}
		//电信
		else if(t == 2){
			urlPath += "cdma_search?"+"sid="+a+"&nid="+b+"&bid="+c+"&hex=0"; 
		}
		else{
			return false;
		}
		StringBuilder rspbuilder = new StringBuilder();
		boolean getPosflg = httpInstance.sendGetMsg(true, urlPath, rspbuilder);
		if(!getPosflg){
			logger.error("send www.juhe.com error!");
		}
		else{
			String httprsp = rspbuilder.toString();
			if(t == 2){
				JHCdmaResult jhcdmaresult = (JHCdmaResult)jsonInstance.String2Obj(httprsp, "fnic.jsontrans.JHCdmaResult");
				if(jhcdmaresult!=null && jhcdmaresult.getResultcode().trim().toLowerCase().equals("2000")){
					cgi.setLatitude(Double.parseDouble(jhcdmaresult.getResult().getLat()));
					cgi.setLongitude(Double.parseDouble(jhcdmaresult.getResult().getLon()));
					cgi.setAddress(jhcdmaresult.getResult().getAddress());
					return true;
				}else{
					logger.error("get cdma rsp, but error!");
				}
			}else{
				JHCellIdResult jhcellidresult = (JHCellIdResult)jsonInstance.String2Obj(httprsp, "fnic.jsontrans.JHCellIdResult");
				if(jhcellidresult!=null && jhcellidresult.getResultcode().trim().toLowerCase().equals("2000")){
					cgi.setLatitude(Double.parseDouble(jhcellidresult.getResult().getLat()));
					cgi.setLongitude(Double.parseDouble(jhcellidresult.getResult().getLon()));
					cgi.setAddress(jhcellidresult.getResult().getAddress());
					return true;
				}else{
					logger.error("get 3gpp rsp, but error!");
				}
			}

		}
		return false;
	}
	
	private static class RadioCGI{
		public int getA() {
			return a;
		}
		public int getB() {
			return b;
		}
		public int getC() {
			return c;
		}
		public int getT() {
			return t;
		}
		public void setA(int a) {
			this.a = a;
		}
		public void setB(int b) {
			this.b = b;
		}
		public void setC(int c) {
			this.c = c;
		}
		public void setT(int t) {
			this.t = t;
		}
		
		public double getLongitude() {
			return longitude;
		}
		public void setLongitude(double longitude) {
			this.longitude = longitude;
		}
		public double getLatitude() {
			return latitude;
		}
		public void setLatitude(double latitude) {
			this.latitude = latitude;
		}
		
		public String getAddress() {
			return address;
		}
		public void setAddress(String address) {
			this.address = address;
		}
		public String getZonecode() {
			return zonecode;
		}
		public void setZonecode(String zonecode) {
			this.zonecode = zonecode;
		}

		int a;      //mnc   sid
		int b;      //lac   nid
		int c;      //cellid bid
		int t;      // 0:移动    1:联通     2:电信
		
		double latitude; //纬度
		double longitude; //经度
		String address;
		String zonecode;
	}

	@Override
	protected void dealSingleIndexRsp(IndexResponse response) {
		// TODO Auto-generated method stub
		if(response!=null)
		{
			phoneCtrl.getindexinfo().setindexid(response.getId());
			phoneCtrl.getindexinfo().setStatus(ErrorCode.index_success);
			phoneCtrl.getindexinfo().setErrorno(0);
		}else{
			phoneCtrl.getindexinfo().setindexid("-2"); //批量索引失败
			phoneCtrl.getindexinfo().setStatus(ErrorCode.index_failed);
			phoneCtrl.getindexinfo().setErrorno(ErrorCode.indexErrCode);
		}
//		sendIdxResult(jsonInstance.Obj2String(phoneCtrl), true);
		sendIdxResult(jsonInstance.Obj2String(phoneCtrlList), true);
		phoneCtrlList = new ArrayList<PhoneJsonToCtrl>();
	}
}
